<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>键盘打字高亮特效-由@tim1103出品</title>
		<style>
			html,
			body {
				background: rgb(25, 25, 25);
				color: rgb(75, 75, 75);
				font-family: Arial, sans-serif;
				font-size: 2.5vmin;
				-webkit-font-smoothing: antialiased;
				margin: 0 auto;
				height: 100%;
				width: 100%;
				text-align: center;
			}

			h1 {
				padding: 0;
				margin-bottom: 0vmin;
				font-size: 2.85vmin;
				text-align: center;
			}

			h2 {
				margin-bottom: 2vmin;
				font-size: 2.5vmin;
				text-align: center;
			}

			a {
				color: rgb(100, 100, 100);
				text-decoration: none;
			}

			a,
			span {
				cursor: pointer;
				border-bottom: 0.25vmin dotted rgb(255, 255, 255);
				-webkit-transition: .5s;
				-moz-transition: .5s;
				-o-transition: .5s;
				-ms-transition: .5s;
				transition: .5s;
			}

			a:hover,
			span:hover {
				color: rgb(255, 255, 255);
				border-bottom: 0.25vmin dotted rgb(75, 75, 75);
			}

			.key-wrapper {
				position: absolute;
				top: calc(50% - 30vmin);
				left: calc(50% - 58vmin);
			}

			ul {
				text-align: center;
				white-space: nowrap;
			}

			li {
				display: inline-block;
				margin: -0.5vmin 0.75vmin;
				width: 5vmin;
				height: 5vmin;
				padding: 1vmin;
				border: 0.25vmin solid rgb(75, 75, 75);
				border-radius: 1vmin;
				line-height: 5vmin;
				text-align: center;
				text-transform: uppercase;
				-moz-user-select: none;
				-khtml-user-select: none;
				-webkit-user-select: none;
				user-select: none;
				-webkit-transition: .5s;
				-moz-transition: .5s;
				-o-transition: .5s;
				-ms-transition: .5s;
				transition: .5s;
			}

			li:hover {
				cursor: pointer;
				color: rgb(255, 255, 255);
			}

			[data-code="32"]

			/*SPACEBAR*/
				{
				width: 40vmin;
			}

			.active {
				-webkit-transition: 0s;
				-moz-transition: 0s;
				-ms-transition: 0s;
				transition: 0s;
				transform: scale(1.15);
			}

			.drum {
				border-color: rgb(0, 255, 100);
				color: rgb(0, 255, 100);
			}

			.drum.active {
				color: rgb(75, 75, 75);
				background-color: rgb(0, 255, 100);
			}

			.pad {
				border-color: rgb(255, 225, 0);
				color: rgb(255, 225, 0);
			}

			.pad.active {
				color: rgb(75, 75, 75);
				background-color: rgb(255, 225, 0);
			}

			.loop {
				border-color: rgb(255, 100, 0);
				color: rgb(255, 100, 0);
			}

			.loop.active {
				color: rgb(75, 75, 75);
				background-color: rgb(255, 100, 0);
			}

			.bass {
				border-color: rgb(255, 0, 75);
				color: rgb(255, 0, 75);
			}

			.bass.active {
				color: rgb(75, 75, 75);
				background-color: rgb(255, 0, 75);
			}

			.synth {
				border-color: rgb(150, 0, 255);
				color: rgb(150, 0, 255);
			}

			.synth.active {
				color: rgb(75, 75, 75);
				background-color: rgb(150, 0, 255);
			}

			.effect {
				border-color: rgb(0, 150, 255);
				color: rgb(0, 150, 255);
			}

			.effect.active {
				color: rgb(75, 75, 75);
				background-color: rgb(0, 150, 255);
			}
		</style>
	</head>
	<body>

		<div class="key-wrapper">

			<h2><span>点击我</span> 让焦点到本页面后，键盘输入查看效果</h2>

			<ul>
				<li class="drum" data-key="1" data-code="49">1</li>
				<li class="drum" data-key="2" data-code="50">2</li>
				<li class="drum" data-key="3" data-code="51">3</li>
				<li class="drum" data-key="4" data-code="52">4</li>
				<li class="synth" data-key="5" data-code="53">a♩</li>
				<li class="synth" data-key="6" data-code="54">b♩</li>
				<li class="synth" data-key="7" data-code="55">c♩</li>
				<li class="synth" data-key="8" data-code="56">d♩</li>
				<li class="synth" data-key="9" data-code="57">e♩</li>
				<li class="synth" data-key="0" data-code="48">f♩</li>
				<li class="synth" data-key="-" data-code="173">g♩</li>
			</ul>

			<ul>
				<li class="drum" data-key="q" data-code="81">q</li>
				<li class="drum" data-key="w" data-code="87">w</li>
				<li class="drum" data-key="e" data-code="69">e</li>
				<li class="drum" data-key="r" data-code="82">r</li>
				<li class="" data-key="t" data-code="84">t</li>
				<li class="bass" data-key="y" data-code="89">y</li>
				<li class="bass" data-key="u" data-code="85">u</li>
				<li class="pad" data-key="i" data-code="73">i</li>
				<li class="pad" data-key="o" data-code="79">o</li>
				<li class="pad" data-key="p" data-code="80">p</li>
			</ul>

			<ul>
				<li class="drum" data-key="a" data-code="65">a</li>
				<li class="drum" data-key="s" data-code="83">s</li>
				<li class="drum" data-key="d" data-code="68">d</li>
				<li class="drum" data-key="f" data-code="70">f</li>
				<li class="" data-key="g" data-code="71">g</li>
				<li class="bass" data-key="h" data-code="72">h</li>
				<li class="bass" data-key="j" data-code="74">j</li>
				<li class="loop" data-key="k" data-code="75">k</li>
				<li class="loop" data-key="l" data-code="76">l</li>
			</ul>

			<ul>
				<li class="drum" data-key="z" data-code="90">z</li>
				<li class="drum" data-key="x" data-code="88">x</li>
				<li class="drum" data-key="c" data-code="67">c</li>
				<li class="drum" data-key="v" data-code="86">v</li>
				<li class="" data-key="b" data-code="66">b</li>
				<li class="" data-key="n" data-code="78">n</li>
				<li class="loop" data-key="m" data-code="77">m</li>
				<li class="loop" data-key="," data-code="188">,</li>
			</ul>

			<ul>
				<li class="effect" data-key="SPACE" data-code="32">SPACE</li>
			</ul>
		</div>
		<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
		<script>
			// Detect Key Events
			// $(window).on("keydown", function(event){
			
			var osc = {};
			
			$(window).keydown(function(event) {
			  var code = (event.keyCode ? event.keyCode : event.which);
			  if(osc[code])
			    return;
			  $("li[data-code='"+code+"']").addClass("active")
			  var key = $("li[data-code='"+code+"']").data("key");
			  var code = $("li[data-code='"+code+"']").data("code");
			  console.log("KEYON:" + key + "/" + code + "@" + event.timeStamp);
			  startSound(code);
			  // $(this).off(event);
			});
			
			$(window).keyup(function(event) {
			  var code = (event.keyCode ? event.keyCode : event.which);
			  $("li[data-code='"+code+"']").removeClass("active")
			  var key = $("li[data-code='"+code+"']").data("key");
			  var code = $("li[data-code='"+code+"']").data("code");
			  console.log("KEYOFF:" + key + "/" + code + "@" + event.timeStamp);
			  if(!osc[code])
			    return;
			  stopSound(code);
			});
			
			
			
			// Detect Mouse Events
			$("li").mousedown(function(event) {
			  $(this).addClass("active");
			  var key = $(this).data("key");
			  var code = $(this).data("code");
			  console.log("MOUSEON:" + key + "/" + code + "@" + event.timeStamp);
			  startSound();
			});
			
			$("li").mouseup(function(event) {
			  $(this).removeClass("active");
			  var key = $(this).data("key");
			  var code = $(this).data("code");
			  console.log("MOUSEOFF:" + key + "/" + code + "@" + event.timeStamp);
			  stopSound();
			});
			
			// Synthesis
			function startSound(key) {
			    ran = Math.floor((Math.random()*500)+10);
			    var o = osc[key] = new Tone.Oscillator(ran, "triangle")
			    env = new Tone.AmplitudeEnvelope();
			        o.connect(env);
			        env.toMaster();
			        // osc.toMaster();
			        o.start();
			        env.triggerAttack();
			}
			function stopSound(key) {
			    env.triggerRelease();
			    osc[key].stop();
			    osc[key] = 0;
			}
		</script>
		<div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';">
		</div>
	</body>
</html>
